﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TeamsPortal.DataAccess;

namespace TeamsPortal.ServiceClient
{
    public class TopicsServiceClient : ITopicsServiceClient
	{
        private IMessagesServiceClient _messageServiceClient;
        private TopicsDataAccess _da = new TopicsDataAccess();

        public TopicsServiceClient(IMessagesServiceClient messageServiceClient)
        {
            _messageServiceClient = messageServiceClient;
        }

		/// <summary>
		/// Gets a list of topics of a forum ordered by views
		/// </summary>
		public List<Topic> GetByForum(int forumId, int startIndex, int length, UserRole? role)
		{
			return _da.GetByForum(forumId, startIndex, length, role);
		}

		/// <summary>
		/// Gets the topics tagged in a certain forum
		/// </summary>
		/// <returns></returns>
		public List<Topic> GetByTag(string tag, int forumId, UserRole? role)
		{
			return _da.GetByTag(tag, forumId, role);
		}

		/// <summary>
		/// Gets a topic by id
		/// </summary>
		/// <param name="topicId"></param>
		/// <returns></returns>
		public Topic Get(int topicId)
		{
			return _da.Get(topicId);
		}
		
		/// <summary>
		/// Gets a topic by id, validating that the shortName matches
		/// </summary>
		public Topic Get(int id, string shortName)
		{
			Topic topic = Get(id);
            //note: what is the reason of the checking?
			if (topic != null && topic.ShortName.ToUpper() != shortName.ToUpper())
			{
				topic = null;
			}
			return topic;
		}

		public void LoadRelatedTopics(Topic topic, int amount)
		{
			topic.Related = _da.GetRelatedTopics(topic, amount);
		}

		/// <exception cref="ValidationException"></exception>
		public void Create(Topic topic, string ip)
		{
			topic.ValidateFields();
			_da.Add(topic, ip);
		}

		/// <summary>
		/// Edits a topic
		/// </summary>
		/// <exception cref="ValidationException"></exception>
		public void Edit(Topic topic, string ip)
		{
			topic.ValidateFields();
			_da.Edit(topic, ip);
		}

		public void AddVisit(int topicId)
		{
			var handler = new Action<int>(AddVisitSync);
			handler.BeginInvoke(topicId, null, null);
		}

		private void AddVisitSync(int topicId)
		{
			_da.AddVisit(topicId);
		}

		public List<Topic> GetLatest(int forumId, int startIndex, int length, UserRole? role, int? userId = null)
		{
            return _da.GetByForumLatest(forumId, startIndex, length, role, userId);
		}

		public List<Topic> GetLatest()
		{
			return _da.GetLatest();
		}

		/// <summary>
		/// Moves a topic from a forum to another.
		/// </summary>
		public Topic Move(int id, int forumId, int userId, string ip)
		{
			_da.Move(id, forumId, userId, ip);
			return _da.Get(id);
		}

		/// <summary>
		/// Closes a topic to disallow further replies.
		/// </summary>
		public void Close(int id, int userId, string ip)
		{
			_da.Close(id, userId, ip);
		}

		/// <summary>
		/// Opens a topic to allow replies.
		/// </summary>
		public void Open(int id, int userId, string ip)
		{
			_da.Open(id, userId, ip);
		}

		/// <summary>
		/// Gets a list of unanswered topics
		/// </summary>
		/// <param name="p"></param>
		/// <returns></returns>
		public List<Topic> GetUnanswered(int forumId, UserRole? role)
		{
			return _da.GetUnanswered(forumId, role);
		}

		/// <summary>
		/// Gets a list of unanswered topics from all forums
		/// </summary>
		/// <returns></returns>
		public List<Topic> GetUnanswered()
		{
			return _da.GetUnanswered();
		}

		/// <summary>
		/// Deletes (inactive) a user from the application
		/// </summary>
		public void Delete(int id, int userId, string ip)
		{
			_da.Delete(id, userId, ip);
		}

		/// <summary>
		/// Gets a list of topics posted by the user
		/// </summary>
		/// <param name="role">Role of the user requesting the page</param>
		public List<Topic> GetByUser(int userId, UserRole? role)
		{
			return _da.GetByUser(userId, role);
		}

		/// <summary>
		/// Gets a list of topics with the messages posted by the user
		/// </summary>
		public List<Topic> GetTopicsAndMessagesByUser(int userId)
		{
			return _da.GetTopicsAndMessagesByUser(userId);
		}

		/// <summary>
		/// Get a topic containing an specific amount of messages starting from firstMsg
		/// </summary>
		public Topic GetMessagesFrom(int topicId, int firstMsg, int amount)
		{
			Topic topic = Get(topicId);
			if (topic != null)
			{
                topic.Messages = _messageServiceClient.GetByTopicFrom(topicId, firstMsg, amount);
			}
			return topic;
		}

		/// <summary>
		/// Gets a topic containing messages from firstMsg to lastMsg
		/// </summary>
		public Topic GetMessages(int topicId, int firstMsg, int lastMsg)
		{
			Topic topic = Get(topicId);
			if (topic != null)
			{
                topic.Messages = _messageServiceClient.GetByTopic(topicId, firstMsg, lastMsg);
			}
			return topic;
		}
	}
}
